package lx6;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

//客户端：将本地文件上传到服务器。接收服务器的反馈。
//服务器：接收客户端上传的文件，上传完毕之后给出反馈。

/*
服务器只能处理一个客户端请求，接收完一个图片之后，服务器就关闭了。
优化方案一：
使用循环
弊端：
第一个用户正在上传数据，第二个用户就来访问了，此时第二个用户是无法成功上传的。
所以，使用多线程改进
优化方案二：
每来一个用户，就开启多线程处理
 */
//客户端：将本地文件上传到服务器。接收服务器的反馈。
//服务器：接收客户端上传的文件，上传完毕之后给出反馈。
/*线程池改进*/
public class Server {
    public static void main(String[] args) throws IOException {
    /*
        流程:1.用FileInputStream读取本地文件
        2.读到内存中以后，再用网络的io传递给服务器
        3.服务器接收到文件以后，用FileOutputStream写入到本地
        4.当写入完毕以后，服务器给出反馈---- 写入成功
         */

        //创建线程池对象
        ThreadPoolExecutor pool = new ThreadPoolExecutor(
                3, //核心线程数
                20, //最大线程数
                60, //空闲时间
                TimeUnit.SECONDS, //时间单位S
                new ArrayBlockingQueue<>(3), //排队的队列3个   任务队列
                Executors.defaultThreadFactory(), //创建线程工厂 其实是线程池如何创建线程对象
                new ThreadPoolExecutor.AbortPolicy() //任务的拒绝策略
        );



        //创建服务器对象绑定端口号
        ServerSocket ss = new ServerSocket(10000);
        while (true) {
            //等待客服端连接，连接成功返回一个socket对象
            Socket socket = ss.accept();
            //只要有一个客服端来连接了，我们就开启一条线程，
            //一个用户就对于服务的的一条线程
     /*       MyThread t = new MyThread(socket);
            t.start();*/


            //提交任务
            pool.submit(new MyThread(socket));

        }

        /* ss.close();//关闭服务器*/
    }
}
